package negocio;

import datos.Certificado;
import datos.EstadoCertificado;
import datos.Pago;
import java.math.BigDecimal;
import java.net.URL;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/***
 *
 * @author Ing. Monica Merlo, Ing. Agustin  Fernandez
 */
@Stateless
public class GestorPagosBean implements GestorPagosRemote, GestorPagosLocal {

    static Logger logger = Logger.getLogger(GestorPagosBean.class);
    public static void log4j (Exception e){
        URL url = GestorPagosBean.class.getResource("/configuracion/log4j.properties");
        PropertyConfigurator.configure(url);
        logger.error(e);
    }

    @PersistenceContext
    private EntityManager em;

    /***
     * Retorna una lista con todos los objetos de tipo Certificado cuyos
     * id de Obra coincidan con el parametro idObra, y ademas cuyos estados
     * sean distintos de 'PAGADO', caso contario retorna Null.
     * @param idObra
     * @return lista de certificados por obra y con estado distinto de 'PAGADO'
     * Interfaz local
     */
    public List verCertificadosObra(int idObra) {
        try {

            javax.persistence.Query q = em.createNamedQuery("Certificado.encontrarPorObraPorEstado");
            q.setParameter("idObra", idObra);
            return q.getResultList();
        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna una lista con todos los objetos de tipo Certificado cuyos
     * id de Obra coincidan con el parametro idObra, y ademas cuyos estados
     * sean distintos de 'PAGADO', caso contario retorna Null.
     * @param idObra
     * @return lista de certificados por obra y con estado distinto de 'PAGADO'
     * Interfaz remota
     */
    public List verCertificadosObraRemote(int idObra) {
        try {

            javax.persistence.Query q = em.createNamedQuery("Certificado.encontrarPorObraPorEstado");
            q.setParameter("idObra", idObra);
            return q.getResultList();
        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return null;
        }
    }

    /***
     * Crea una nueva instancia de tipo Pago retornando True en caso de exito y False en
     * caso contrario.
     * @param numero
     * @param fecha
     * @param observaciones
     * @param monto
     * @param montoCertificado
     * @param idCertificado
     * @param idEstado
     * @param estado
     * @param saldoCertificado
     * @param numeroCheque
     * @param tipoCheque
     * @param emisor
     * @param numeroCtaCorriente
     * @param banco
     * @param nroSucursal
     * @return true si el nuevo pago persiste con exito, y false si no persiste con exito
     * Interfaz local
     */
    public boolean agregarPago(int numero, Date fecha, String observaciones, BigDecimal monto, BigDecimal montoCertificado, int idCertificado, int idEstado, String estado, BigDecimal saldoCertificado, int numeroCheque, String tipoCheque, String emisor, String numeroCtaCorriente, String banco, int nroSucursal) {
        try {
            Pago p = new Pago();
            p.setNumero(numero);
            p.setFecha(fecha);
            p.setMonto(monto);
            p.setObservaciones(observaciones.toUpperCase());
            p.setNumeroCheque(numeroCheque);
            p.setTipoCheque(tipoCheque);
            p.setEmisor(emisor.toUpperCase());
            p.setNumeroCtaCorriente(numeroCtaCorriente);
            p.setBanco(banco.toUpperCase());
            p.setNroSucursal(nroSucursal);
            Certificado cert = (Certificado) em.find(Certificado.class, idCertificado);
            p.setIdCertificado(cert);
            EstadoCertificado estadoCertificado;
            if (saldoCertificado.compareTo(monto) == 1) {
                estadoCertificado = this.encontrarEstadoPorNombre("PAGADO PARCIAL");
                p.getIdCertificado().setIdEstado(estadoCertificado);

            } else if (saldoCertificado.compareTo(monto) == 0) {
                estadoCertificado = this.encontrarEstadoPorNombre("PAGADO");
                p.getIdCertificado().setIdEstado(estadoCertificado);
            }

            persist(p);
            em.flush();
            return true;
        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return false;
        }
    }

    /***
     * Crea una nueva instancia de tipo Pago retornando True en caso de exito y False en
     * caso contrario.
     * @param numero
     * @param fecha
     * @param observaciones
     * @param monto
     * @param montoCertificado
     * @param idCertificado
     * @param idEstado
     * @param estado
     * @param saldoCertificado
     * @param numeroCheque
     * @param tipoCheque
     * @param emisor
     * @param numeroCtaCorriente
     * @param banco
     * @param nroSucursal
     * @return true si el nuevo pago persiste con exito, y false si no persiste con exito
     * Interfaz remota
     */
    public boolean agregarPagoRemote(int numero, Date fecha, String observaciones, BigDecimal monto, BigDecimal montoCertificado, int idCertificado, int idEstado, String estado, BigDecimal saldoCertificado, int numeroCheque, String tipoCheque, String emisor, String numeroCtaCorriente, String banco, int nroSucursal) {
        try {
            Pago p = new Pago();
            p.setNumero(numero);
            p.setFecha(fecha);
            p.setMonto(monto);
            p.setObservaciones(observaciones.toUpperCase());
            p.setNumeroCheque(numeroCheque);
            p.setTipoCheque(tipoCheque);
            p.setEmisor(emisor.toUpperCase());
            p.setNumeroCtaCorriente(numeroCtaCorriente);
            p.setBanco(banco.toUpperCase());
            p.setNroSucursal(nroSucursal);
            Certificado cert = (Certificado) em.find(Certificado.class, idCertificado);
            p.setIdCertificado(cert);
            EstadoCertificado estadoCertificado;
            if (saldoCertificado.compareTo(monto) == 1) {
                estadoCertificado = this.encontrarEstadoPorNombre("PAGADO PARCIAL");
                p.getIdCertificado().setIdEstado(estadoCertificado);

            } else if (saldoCertificado.compareTo(monto) == 0) {
                estadoCertificado = this.encontrarEstadoPorNombre("PAGADO");
                p.getIdCertificado().setIdEstado(estadoCertificado);
            }

            persist(p);
            em.flush();
            return true;
        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return false;
        }
    }

    /***
     * 
     * @param objeto
     */
    private void persist(Object objeto) {
        em.persist(objeto);
    }

    /***
     * Retorna un objeto de tipo EstadoCertificado cuyo nombre coincida con
     * el parametro nombre, en caso contrario retorna Null.
     * @param nombre
     * @return estado de certificado
     * Interfaz local
     */
    public EstadoCertificado encontrarEstadoPorNombre(String nombre) {
        try {

            javax.persistence.Query q = em.createNamedQuery("EstadoCertificado.findByNombre");
            q.setParameter("nombre", nombre.toUpperCase().toString());
            EstadoCertificado e = (EstadoCertificado) q.getSingleResult();
            return e;
        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna un objeto de tipo EstadoCertificado cuyo nombre coincida con
     * el parametro nombre, en caso contrario retorna Null.
     * @param nombre
     * @return estado de certificado
     * Interfaz remote
     */
    public EstadoCertificado encontrarEstadoPorNombreRemote(String nombre) {
        try {

            javax.persistence.Query q = em.createNamedQuery("EstadoCertificado.findByNombre");
            q.setParameter("nombre", nombre.toUpperCase().toString());
            EstadoCertificado estadoCertificado = (EstadoCertificado) q.getSingleResult();
            return estadoCertificado;
        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna una lista con objetos de tipo Pago que posean referencia a algun objeto de tipo
     * Certificado, es decir, cuyo id de Certificado coincida con el parametro idCertificado,
     * en caso contrario retorna Null.
     * @param idCertificado
     * @return lista de los pagos por certificado
     * Interfaz remota
     */

    public List existePagoRemote(int idCertificado) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Pago.encontrarPagosPorCertificado");
            q.setParameter("idCertificado", idCertificado);
            return q.getResultList();

        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna una lista con objetos de tipo Pago que posean referencia a algun objeto de tipo
     * Certificado, es decir, cuyo id de Certificado coincida con el parametro idCertificado,
     * en caso contrario retorna Null.
     * @param idCertificado
     * @return lista de los pagos por certificado
     * Interfaz local
     */
     public List existePago(int idCertificado) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Pago.encontrarPagosPorCertificado");
            q.setParameter("idCertificado", idCertificado);
            return q.getResultList();

        } catch (Exception e) {
            GestorPagosBean.log4j(e);
            return null;
        }
    }
}
